package me.xiaolei.float_window

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import java.lang.Exception
import java.lang.RuntimeException

internal class FloatDelegateImpl(
    private val context: Context,
    private val draggable: Boolean,
    private var onUpdate: OnUpdateListener? = null,
    private var onShow: OnShowListener? = null,
    private var onHide: OnHideListener? = null,
    private var onDestroy: OnDestroyListener? = null,
    private var permissionAdapter: PermissionAdapter? = null,
    private var onPosUpdate: OnPositionUpdateListener? = null,
    private val windowManager: WindowManager,
    private val params: WindowManager.LayoutParams,
    private val viewHolder: ViewHolder
) : IFloatDelegate
{
    private var status = Status.INIT

    /**
     * 是否显示
     */
    override fun isShowing(): Boolean = status == Status.SHOW

    /**
     * 显示
     */
    override fun show(): Boolean
    {
        val rootView = viewHolder.rootView

        when (status)
        {
            Status.HIDE ->
            {
                rootView.visibility = View.VISIBLE
                this.onShow?.onShow(viewHolder)
                return true
            }
            Status.SHOW ->
            {
                return true
            }
            Status.DESTROY ->
            {
                return false
            }
        }

        permissionAdapter ?: throw RuntimeException(
            """
            没有设置权限适配器，程序不能正确判断权限
            设置权限适配器：
                FloatViewBuilder.permissionAdapter()
        """.trimIndent()
        )

        // 由外部的权限适配器来判断权限
        if (permissionAdapter?.hasPermission(context) == true)
        {
            try
            {
                this.tryShowView(rootView)
                return true
            } catch (e: Exception)
            {
                e.printStackTrace()
            }
        } else
        {
            // 由外部的权限适配器来申请权限
            permissionAdapter?.startRequestPermission(context) { success ->
                if (success)
                {
                    this.tryShowView(rootView)
                }
            }
        }
        return false
    }

    /**
     * 尝试显示控件
     */
    @Throws(Exception::class)
    private fun tryShowView(view: View)
    {
        if (view.parent == null && status == Status.INIT)
        {
            windowManager.addView(view, params)
            if (draggable)
            {
                this.setTouchListener(view)
            }
            this.onShow?.onShow(viewHolder)
        }
    }

    /**
     * 触摸事件
     */
    @SuppressLint("ClickableViewAccessibility")
    private fun setTouchListener(view: View)
    {
        var downX = 0f
        var downY = 0f

        var startX = 0
        var startY = 0
        view.setOnTouchListener { v, event ->
            when (event.action)
            {
                MotionEvent.ACTION_DOWN ->
                {
                    downX = event.rawX
                    downY = event.rawY
                    startX = params.x
                    startY = params.y
                }
                MotionEvent.ACTION_MOVE ->
                {
                    val diffX = (event.rawX - downX)
                    val diffY = (event.rawY - downY)
                    params.x = (startX + diffX).toInt()
                    params.y = (startY + diffY).toInt()
                    windowManager.updateViewLayout(v, params)
                    this.onPosUpdate?.onUpdate(params.x, params.y)
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL ->
                {

                }
            }
            true
        }
    }

    /**
     * 隐藏
     */
    override fun hide()
    {
        if (status != Status.DESTROY)
        {
            val rootView = viewHolder.rootView
            rootView.visibility = View.INVISIBLE
            this.onHide?.onHide(viewHolder)
            status = Status.HIDE
        }
    }

    /**
     * 更新数据
     */
    override fun update(bundle: Bundle)
    {
        this.onUpdate?.onUpdate(bundle, viewHolder)
    }

    /**
     * 销毁
     */
    @Synchronized
    override fun destroy()
    {
        if (status != Status.DESTROY)
        {
            val rootView = viewHolder.rootView
            windowManager.removeView(rootView)
            status = Status.DESTROY
            this.onDestroy?.onDestroy(viewHolder)
            this.release()
        }
    }

    /**
     * 释放资源
     */
    private fun release()
    {
        this.onUpdate = null
        this.onDestroy = null
        this.onHide = null
        this.onShow = null
        this.permissionAdapter = null
        this.onPosUpdate = null
    }


    enum class Status
    {
        /**
         * 初始化
         */
        INIT,

        /**
         * 显示
         */
        SHOW,

        /**
         * 隐藏
         */
        HIDE,

        /**
         * 销毁
         */
        DESTROY
    }
}